package com.huluobo.a2205kotlinjetpackdemo.coroutine

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.huluobo.base.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.lang.Exception

class CoroutineActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_coroutine)

//        //创建协程,相当于newThread
//        //IO代表工作线程,也就是子线程
//        val job = GlobalScope.launch(Dispatchers.IO) {
//            Log.i("TagA", "当前线程:${Thread.currentThread()}")
//        }
//
//        job.cancel()
//        //Main 代表主线程,大括号中的内容全部运行在主线程当中
//        GlobalScope.launch(Dispatchers.Main) {
//            Log.i("TagA", "当前线程:${Thread.currentThread()}")
//        }

        val job = Job()
        CoroutineScope(job).launch {
//            val result = async {
//                try {
//                    delay(5000)
//                    "运算结果:${3 / 1}"
//                } catch (e: Exception) {
//                    "结果异常"
//                }
//            }.await()
//            Log.i("TagA", "result:$result")
            val startTime = System.currentTimeMillis()
            val result = async {
                delay(2000)
                "操作成功"
            }

            val reuslt2 = async {
                delay(1000)
                "获取成功"
            }
            Log.i("TagA", "执行结果:${result.await()},${reuslt2.await()}")
            val endTime = System.currentTimeMillis()
            Log.i("TagA", "执行时间:${endTime - startTime}")

            loadData()
        }

        CoroutineScope(job).launch(Dispatchers.Main) {
            //Dispatchers.Main 表示在程序主线程中运行,所以在开启协程时,他的代码不一定是在子线程中执行的,也可以随时进行切换
            //Dispatchers.IO 常用于耗时操作,比如网络请求,或者文件读写,数据库等
            //Dispatchers.Unconfined 不配置,不去处理不去配置,一般不会用到
            //Dispatchers.Default 表示默认,协程交给系统处理,一般用于计算密集型

            val result = withContext(Dispatchers.IO) {
                delay(2000)
                "操作成功"
            }
            Log.i("TagA", "result:$result")
        }
    }

    //系统并不知道一个方法是否需要在协程中执行,所以需要加上suspend(挂起)来提示其他开发者,当前方法需要在协程中才能调用

    private suspend fun loadData() {
        delay(2000)
        Log.i("TagA", "loadData")
    }

    private suspend fun loadData2() {
        loadData()
    }
}